﻿using KAKA.Domain;
using KAKA.Models;
using KAKA.Repository;
using KAKA.Repository.Specification;
using KAKA.Service;
using Morus;
using MvcContrib;
using System;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;

namespace KAKA.Controllers
{
    public class HomeController : BaseController
    {
        public HomeController()
            : base()
        {
            EventRepository = IoC.Resolve<IEventRepository>();
            MemberRepository = IoC.Resolve<IMemberRepository>();
        }

        public IEventRepository EventRepository { get; private set; }
        public IMemberRepository MemberRepository { get; private set; }

        public ActionResult Index()
        {
            var newlyGirls = MemberRepository.GetNewlyGirls(DateTime.Today.AddDays(-30), 4);
            var newlyBoys = MemberRepository.GetNewlyBoys(DateTime.Today.AddDays(-30), 4);

            var vipGirls = MemberRepository.Find(new VipMemberSpecification(Gender.Female));
            var vipBoys = MemberRepository.Find(new VipMemberSpecification(Gender.Male));

            var events = EventRepository.GetAll()
               .ToList()
               .Where(r => !r.IsHidden)
               .OrderByDescending(r => r.ActAt);

            var latest = events.FirstOrDefault();

            var recommand = events.Skip(1).Take(3)
                .ToList();

            ViewBag.LatestEvent = latest;
            ViewBag.RecommandEvents = recommand;

            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Login()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Login(LoginModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var user = UserRepository.Get(model.Username);

                if (user != null)
                {
                    if (user.Verify(model.Username, model.Password))
                    {
                        FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);

                        if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                            && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                        {
                            return Redirect(returnUrl);
                        }
                        else
                        {
                            return this.RedirectToAction(r => r.Index());
                        }
                    }
                    else
                    {
                        ModelState.AddModelError(string.Empty, Resources.Error_4001_Sign_Info_Is_Invalid);
                    }
                }
            }

            return View();
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult SignUp()
        {
            return View();
        }

        [ValidateAntiForgeryToken]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult SignUp(SignUpModel model)
        {
            var user = Domain.User.Create(model.Username, model.Password, model.Gender, model.Nickname);

            if (!user.IsUnique())
            {
                ModelState.AddModelError("", Resources.Error_4000_Email_Has_Exist);
            }

            if (ModelState.IsValid)
            {
                using (var uow = UnitOfWork.Begin())
                {
                    UserRepository.Add(user);

                    var token = Guid.NewGuid();

                    user.Proofs.Add(new Proof
                    {
                        Id = Guid.NewGuid(),
                        CreateAt = DateTime.Now,
                        User = user,
                        Email = user.Email,
                        Value = Convert.ToBase64String(token.ToByteArray()),
                    });

                    uow.Commit();

                    FormsAuthentication.SetAuthCookie(model.Username, false);

                    EventAggregator.GetEvent<RegistrationEvent>().Publish(new RegistrationEventArgs(user, token));

                    return this.RedirectToAction("Basic", "Personal", new { welcome = true });
                }
            }

            return View();
        }

        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();

            return this.RedirectToAction(r => r.Index());
        }

        [Authorization]
        public ActionResult ChangePassword()
        {
            return View();
        }

        [Authorization]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            //if (ModelState.IsValid)
            //{

            //    // ChangePassword will throw an exception rather
            //    // than return false in certain failure scenarios.
            //    bool changePasswordSucceeded;
            //    try
            //    {
            //        MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
            //        changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
            //    }
            //    catch (Exception)
            //    {
            //        changePasswordSucceeded = false;
            //    }

            //    if (changePasswordSucceeded)
            //    {
            //        return RedirectToAction("ChangePasswordSuccess");
            //    }
            //    else
            //    {
            //        ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
            //    }
            //}

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        public ActionResult ResetPassword()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ResetPassword(ResetPasswordModel model)
        {
            var user = UserRepository.Get(model.Email);
            if (user != null)
            {
                EventAggregator.GetEvent<ResetPasswordEvent>().Publish(new ResetPasswordEventArgs(CurrentUser));
            }

            return this.RedirectToAction(r => r.ResetPasswordSuccess());
        }

        public ActionResult ResetPasswordSuccess()
        {
            return View();
        }
    }
}
